home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Alles Voor Internet / Tout Pour Internet
/
alles voor internet.iso
/
MacInternet™
/
Telnet
/
NCSA
/
tn3270 2.4d7 source
/
tn3270
/
tcpio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-17
|
34KB
|
1,475 lines
/*
* tn3270 for the Macintosh Source Code
* Brown University Computing and Information Services
* Version 2.4d7 April, 1992
* Copyright (c) 1988, 1989, 1990, 1991, 1992 by Brown University and by
* Peter John DiCamillo.
*
* Permission is granted to any individual or institution to use, copy,
* or redistribute the binary version of this software and its
* documentation provided this notice and the copyright notices are
* retained. Permission is granted to any individual or non-profit
* institution to use, copy, modify, or redistribute the source files
* of this software provided this notice and the copyright notices are
* retained. This software may not be distributed for profit, either
* in original form or in derivative works, nor can the source be
* distributed to other than an individual or a non-profit institution.
* Any individual or group interested in seeing and/or using these
* source files but who are prevented from doing so by the above
* constraints should contact Don Wolfe, Assistant Vice-President for
* Computer Systems at Brown University, (401) 863-7250, for possible
* software licensing of the source developed at Brown.
*
* Brown University and Peter John DiCamillo make no representations
* about the suitability of this software for any purpose.
*
* BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
* EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
* INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#if !defined(USEDUMP)
#include "maclib.h"
#include "termdef.h"
#include "tn3270funcs.h"
#include "globals.h"
#else
#pragma load "tn3270DumpFile"
#endif
#include <AppleTalk.h>
#include "kip.h"
#include "netevent.h"
#include "hostform.h"
#include "NCSAfuncs.h" /* must follow hostform.h */
#pragma segment 3270tcp
#define CFIGFILE "\pNCSA Telnet Settings"
#define HTELNET 23
unsigned char myipnum[4]; /* my IP number */
long kipns; /* name server from KIP */
long mynetmask; /* my network mask */
unsigned char KIPserver[4]; /* AppleTalk address of KIP gateway */
int KIP; /* KIP gateway is present */
int HFS; /* HFS file system being used */
extern int EtherNet; /* "The all-powerful! */
#ifdef TCPDRV
static unsigned char KIPzone[33] = "\p*"; /* just to keep the linker happy */
static unsigned char *KIPnameptr;
#else
extern unsigned char KIPzone[33]; /* zone for KIP from config file */
extern unsigned char *KIPnameptr; /* NamesTableEntry pointer for KIP */
#endif
char unldATP; /* flag to unload .ATP driver */
char unldNBP; /* flag to unload NBP */
#ifdef TCPDRV
char needResClose; /* flag to close DNR resolver */
#endif
char dynam; /* myipnum was obtained dynamically */
char snetmask; /* mask was obtained from file */
char kipreg; /* flag to unregister address */
NamesTableEntry myreg; /* my registration entry */
short savedvol; /* saved volref to restore after configuration */
char tcpinitok = 0; /* tcp network stuff active */
extern short launchvol; /* default volume when we were launched */
extern int button; /* true if mouse down at startup */
extern char ftpavail; /* flag for FTP enabled */
extern short systemvol; /* volume with system files */
extern struct Point sfgpoint; /* SFGetFile location */
extern main(); /* for debugging */
#include "stdio.h"
unsigned char * rcvbuff;
short rcvmax;
#ifdef TCPDRV
OSErr OpenResolver(unsigned char *fileName);
OSErr CloseResolver(void);
#endif
OSErr tcp_init(void)
{
long *HFSp= (long *)1014;
Handle version;
short i, ioerror;
#ifdef TCPDRV
OSErr rc;
#endif
putln("tcp_init called");
/* version info. for debugging */
strcpy(dbgmsg, "Version string: ");
version = GetResource('GFTM', 0);
if (version != 0) {
i = strlen(dbgmsg);
memcpy(dbgmsg+i, (*version)+1, (*version)[0]);
dbgmsg[i+(*version)[0]] = 0;
}
else strcpy(dbgmsg, "Version string not available.");
putln(dbgmsg);
strcpy(dbgmsg, "VM file transfer version: ");
version = GetResource('WSFR', 161);
if (version != 0) {
i = strlen(dbgmsg);
memcpy(dbgmsg+i, (*version)+13, (*version)[12]-1);
dbgmsg[i+(*version)[12]-1] = 0;
while (dbgmsg[i] != 0) {
dbgmsg[i] = ((unsigned char *)(*xtabh))[dbgmsg[i]];
i++;
}
}
else strcpy(dbgmsg, "VM file transfer version unknown.");
putln(dbgmsg);
sprintf(dbgmsg, "main at %lx", main); /* in case we're using a map */
putln(dbgmsg); /* for debugging */
KIP = 0; /* no KIP gateway yet */
HFS = (*HFSp) > 0L; /* check if under HFS */
unldATP = 0; /* haven't loaded ATP */
unldNBP = 0; /* haven't loaded NBP */
#ifdef TCPDRV
needResClose = 0; /* haven't opened resolver */
#endif
kipreg = 0; /* haven't registered our address */
kipns = 0; /* no nameserver from KIP */
/* allocate buffers */
rcvbuff = (unsigned char *)NewPtr(614L); /* 550 + 64 */
if (rcvbuff == 0L) {
stgalert("tcp rcv buffer", "NewPtr", 614L);
return(-1);
}
rcvmax = 512;
/* save current volume, and attempt to find config.tel */
GetVol(dbgmsg, &savedvol);
checkhostfile();
#ifdef TCPDRV
rc = OpenResolver(0);
if (rc != noErr) {
sprintf(dbgmsg, "Unable to open MacTCP: Result code %d from OpenResolver.", rc);
putln(dbgmsg);
stopterr(dbgmsg, 0);
DisposPtr(rcvbuff);
return(-2);
}
needResClose = 1;
#endif
/* initialize and get host information */
ioerror = Snetinit(); /* calls initipnum() */
sprintf(dbgmsg, "return code %d from Snetinit", ioerror);
putln(dbgmsg);
SetVol(0L, savedvol); /* restore initial volume */
if ((ioerror != 0) && (ioerror != -2)) {
ShowAllErrors();
#ifdef TCPDRV
CloseResolver();
#endif
DisposPtr(rcvbuff);
return(-3);
}
tcpinitok = 1; /* call Stask shutdown net stuff */
/* if (ioerror == -2) ioerror = reconfigNetwork(); */ /* RARP failed */
if (ioerror != 0) {
ShowAllErrors();
netshut();
tcpinitok = 0;
#ifdef TCPDRV
CloseResolver();
#endif
DisposPtr(rcvbuff);
return(-4);
}
if (EtherNet)
dynam = (myipnum[0] == 'R') && (myipnum[1] == 'A') &&
(myipnum[2] == 'R') && (myipnum[3] == 'P');
netgetip(myipnum); /* get net number, in case RARPed */
netgetmask((unsigned char *)&mynetmask); /* mask may have changed too */
ftpavail = Sfmode(); /* get initial FTP settings */
return(0);
}
int initipnum(int dummy)
/* "dummy" used to be "button" */
{
#pragma unused(dummy)
NTElement lkpresult;
BDSType retBDS;
IPGP gateSend, gateRec;
short count, rc;
unsigned char nsaddr[4];
short ioerror;
/* open AppleTalk drivers if not using Ethernet */
if (!EtherNet) {
ioerror = openatdrv();
if (ioerror != 0) quit();
/* check for KIP gateway, and if found load number from it */
ioerror = NBld(); /* attempt to load NBP */
if (ioerror != 0) {
stoperr(loadalrt, 0);
quit();
}
/* look for gateway */
rc = nblookup("\p=", "\pIPGATEWAY", KIPzone, &lkpresult, &count);
sprintf(dbgmsg, "rc = %d, count = %d looking for =:IPGATEWAY@%p",
rc, count, KIPzone);
putln(dbgmsg);
if ((rc == 0) && (count > 0)) {
KIP = 1;
memcpy(KIPserver, &lkpresult.nteAddress, 4); /* get gateway addr. */
retBDS[0].buffSize = sizeof(gateRec); /* get nameserver address */
retBDS[0].buffPtr = (Ptr)&gateRec;
gateSend.opcode = 3;
rc = atsend((AddrBlock *)KIPserver, (unsigned char *)&gateSend,
sizeof(struct IPGP), (BDSPtr)retBDS);
if (rc == 0) { /* got an address */
kipns = gateRec.ipname;
if (kipns != 0) {
Ssetns((unsigned char *)&kipns);
memcpy(nsaddr, &kipns, 4);
sprintf(dbgmsg,
"Using name server address from gateway: %d.%d.%d.%d",
nsaddr[0], nsaddr[1], nsaddr[2], nsaddr[3]);
putln(dbgmsg);
}
else {
sprintf(dbgmsg,
"Name server address not available from gateway.");
putln(dbgmsg);
}
}
else {
sprintf(dbgmsg, "Return code %d getting nameserver address", rc);
putln(dbgmsg);
}
}
}
else KIP = 0;
ioerror = getipinfo(); /* try to get IP number and mask */
if (button || (ioerror != 0)) {
ioerror = promptip(0); /* get info from user */
if (ioerror != 0) stoperr(cfigalrt, 0); /* report error saving config */
ioerror = getipinfo(); /* try again */
if (ioerror != 0) { /* exit with error if still failed */
stoperr(addralrt, 0);
quit();
}
}
if (KIP) { /* for KIP, need to register number */
ioerror = kpregister(myipnum);
if (ioerror != 0) { /* exit with error if failed */
stoperr(regalrt, 0);
quit();
}
else kipreg = 1;
}
netsetip(myipnum); /* set IP number */
netsetmask((unsigned char *)&mynetmask); /* set network mask */
putln("initipnum done");
return(0);
}
short getipinfo(void) /* get IP number and mask */
{
short error, rc;
unsigned char strbuf[256];
long dfltmask;
mynetmask = 0; /* initialize mask */
dynam = 0; /* no dynamic number yet */
snetmask = 0; /* no mask from file */
/* get IP number */
error = getstr(strbuf, 256, 256);
if (error == 0) error = decodeIPnum(strbuf, myipnum);
if (error) putln("no IP number from resource");
else putln("got IP number from resource");
if (error) {
if (EtherNet) { /* dynamic if Ether and no IP number */
strncpy(myipnum, "RARP", 4);
dynam = 1;
error = 0;
putln("using RARP");
}
else if (KIP) { /* dynamic if KIP and no IP number */
error = kpdynamip((long *)myipnum);
if (!error) {
dynam = 1;
putln("got dynamic IP number");
}
}
}
/* get subnet mask */
if (!error) {
rc = getstr(strbuf, 256, 258);
if (rc == 0) {
if (sscanf(strbuf, "%lx", &mynetmask) != 1)
calcmask(&mynetmask);
else {
calcmask(&dfltmask);
snetmask = (mynetmask != dfltmask);
}
}
else calcmask(&mynetmask);
sprintf(dbgmsg, "net mask = %08lx", mynetmask);
putln(dbgmsg);
}
if (error) {
memset(myipnum, 0, 4); /* ipnum = 0 if errors */
mynetmask = 0; /* mask too */
putln("error from getipinfo");
}
return(error);
}
OSErr promptip(short ro)
{
DialogPtr dlgptr;
DialogPeek dStorage;
WindowPtr behind;
pascal Boolean (*filterProc) ();
short oldHit, itemHit;
short gtype;
Handle iphandle, dynamhandle, maskhandle;
Rect gbox;
unsigned char ipstr[30], maskstr[20], change;
unsigned char tempnum[20];
OSErr rc;
short rfile;
int hi, low, node;
Size ressize;
Handle temph;
char rarp;
#ifdef TCPDRV
if (ro) showdrv();
return(0);
#endif
dStorage = 0;
behind = (WindowPtr)-1; /* 272 = r/w, 273 = r/o */
dlgptr = GetNewDialog(272+ro, dStorage, behind);
ctrwindow(dlgptr);
/* get handles to various items */
GetDItem(dlgptr, 3, >ype, &iphandle, &gbox);
GetDItem(dlgptr, 4, >ype, &dynamhandle, &gbox);
GetDItem(dlgptr, 7, >ype, &maskhandle, &gbox);
/* get initial settings */
/* disable dynamic address if AppleTalk and no KIP */
if (!EtherNet && !KIP) HiliteControl((ControlHandle)dynamhandle, 255);
/* set ip number radio buttons */
if (!ro) setit(2, dlgptr, (!dynam));
setit(4, dlgptr, dynam && (KIP || EtherNet));
/* set current ip number */
rc = 4;
if (!ro) rc = getstr(ipstr, 30, 256);
if (rc != 0) {
rarp = (myipnum[0] == 'R') && (myipnum[1] == 'A') &&
(myipnum[2] == 'R') && (myipnum[3] == 'P');
if (!rarp) sprintf(ipstr, "%d.%d.%d.%d", myipnum[0], myipnum[1],
myipnum[2], myipnum[3]);
else strcpy(ipstr, "0.0.0.0");
}
c2pstr(ipstr);
SetIText(iphandle, ipstr);
/* set current ip mask */
cvtmask(mynetmask, maskstr);
c2pstr(maskstr);
SetIText(maskhandle, maskstr);
/* set "use subnetting" check box */
setit(5, dlgptr, snetmask);
/* for info. display, get AppleTalk numbers */
if (ro) {
if (EtherNet) hi = low = node = 0;
else getATaddress( &hi, &low, &node);
sprintf(tempnum, "%d.%d", hi, low);
GetDItem(dlgptr, 10, >ype, &temph, &gbox);
c2pstr(tempnum);
SetIText(temph, tempnum);
sprintf(tempnum, "%d", node);
GetDItem(dlgptr, 12, >ype, &temph, &gbox);
c2pstr(tempnum);
SetIText(temph, tempnum);
GetDItem(dlgptr, 13, >ype, &temph, &gbox);
if (EtherNet) SetIText(temph, "\p[RARP]");
else if (KIP) SetIText(temph, "\p[KIP]");
}
else {
GetDItem(dlgptr, 9, >ype, &temph, &gbox);
if (EtherNet) SetIText(temph, "\p[RARP]");
else if (KIP) SetIText(temph, "\p[KIP]");
}
/* ready to display the dialog */
ShowWindow(dlgptr);
arrowcursor();
/* frame the default selection */
framedflt(dlgptr);
filterProc = DlgFilter;
oldHit = 0;
change = 0;
while(1) {
ModalDialog(filterProc, &itemHit);
if (itemHit != 1) change = 1;
if ((oldHit > 0) && (oldHit != itemHit))
switch(oldHit) {
case 3: /* IP number editText */
GetIText(iphandle, ipstr);
p2cstr(ipstr);
rc = decodeIPnum(ipstr, tempnum);
if (rc) SetIText(iphandle, "\p0.0.0.0");
break;
case 7: /* mask editText */
GetIText(maskhandle, maskstr);
p2cstr(maskstr);
if (sscanf(maskstr, "%lx", &mynetmask) != 1)
calcmask(&mynetmask);
cvtmask(mynetmask, maskstr);
c2pstr(maskstr);
SetIText(maskhandle, maskstr);
break;
default:
break;
}
oldHit = itemHit;
switch(itemHit) {
case 2: /* IP number buttons */
case 4:
dynam = (itemHit == 4);
setit(2, dlgptr, (!dynam));
setit(4, dlgptr, dynam);
break;
case 5: /* use subnetting box */
snetmask ^= 1;
setit(5, dlgptr, snetmask);
break;
}
if (itemHit == 1) break;
}
/* just return if only "OK" was hit or r/o */
if ((!change) || ro) {
DisposDialog(dlgptr);
return(0);
}
/* set ipstr and maskstr to the text to save */
/* use number unless dynamic specified */
if (dynam) ipstr[0] = 0;
else {
GetIText(iphandle, ipstr);
p2cstr(ipstr);
}
/* use mask if subnetting requested */
if (snetmask) {
GetIText(maskhandle, maskstr);
p2cstr(maskstr);
}
else maskstr[0] = 0;
/* done with dialog now */
DisposDialog(dlgptr);
/* delete any existing number and mask resources */
sysvol(0);
rfile = OpenResFile(CFIGFILE);
if (rfile != -1) {
temph = GetResource('STR ', 256);
if (temph != 0) if (HomeResFile(temph) == rfile) {
RmveResource(temph);
}
temph = GetResource('STR ', 258);
if (temph != 0) if (HomeResFile(temph) == rfile) {
RmveResource(temph);
}
CloseResFile(rfile);
}
else {
Create(CFIGFILE, 0, 'NCSA', 'IPNO');
CreateResFile(CFIGFILE);
}
/* return if not storing number and mask */
if ((ipstr[0] == 0) && (maskstr[0] == 0)) {
sysvol(1);
return(0);
}
/* get handles to strings to write out */
if (ipstr[0] != 0) {
c2pstr(ipstr);
ressize = ipstr[0] + 1;
iphandle = NewHandle(ressize);
if (iphandle == 0) {
sysvol(1);
return(1);
}
memcpy((*iphandle), ipstr, ipstr[0]+1);
}
else iphandle = 0;
if (maskstr[0] != 0) {
c2pstr(maskstr);
ressize = maskstr[0] + 1;
maskhandle = NewHandle(ressize);
if (maskhandle == 0) {
if (iphandle != 0) DisposHandle(iphandle);
sysvol(1);
return(2);
}
memcpy((*maskhandle), maskstr, maskstr[0]+1);
}
else maskhandle = 0;
/* write the required resources */
rfile = OpenResFile(CFIGFILE);
if ((ResError() == 0) && (iphandle != 0))
AddResource(iphandle, 'STR ', 256, "\pIP Number");
if ((ResError() == 0) && (maskhandle != 0))
AddResource(maskhandle, 'STR ', 258, "\pNetwork Mask");
rc = ResError();
if (rfile != -1) CloseResFile(rfile);
if (rc == 0) rc = ResError();
sysvol(1);
return(rc);
}
void updhostrsc(unsigned char *s) /* store new default host name */
{
short rfile;
Handle temph;
Size ressize;
/* delete any existing host resource */
sysvol(0);
rfile = OpenResFile(CFIGFILE);
if (rfile != -1) {
temph = GetResource('STR ', 257);
if (temph != 0) if (HomeResFile(temph) == rfile) {
RmveResource(temph);
}
CloseResFile(rfile);
}
else {
Create(CFIGFILE, 0, 'NCSA', 'IPNO');
CreateResFile(CFIGFILE);
}
/* return if not storing host name */
if (s[0] == 0) {
sysvol(1);
return;
}
/* get handles to string to write out */
c2pstr(s);
ressize = s[0] + 1;
temph = NewHandle(ressize);
if (temph == 0) {
p2cstr(s);
sysvol(1);
return;
}
memcpy((*temph), s, s[0]+1);
p2cstr(s);
/* write the required resource */
rfile = OpenResFile(CFIGFILE);
if ((ResError() == 0) && (temph != 0)) {
AddResource(temph, 'STR ', 257, "\pDefault Host");
}
if (rfile != -1) {
CloseResFile(rfile);
}
sysvol(1);
return;
}
void showdrv(void)
{
DialogPtr dlgptr;
DialogPeek dStorage;
WindowPtr behind;
pascal Boolean (*filterProc) ();
short itemHit;
short gtype;
Handle iphandle;
Rect gbox;
unsigned char ipstr[30];
dStorage = 0;
behind = (WindowPtr)-1;
dlgptr = GetNewDialog(280, dStorage, behind);
ctrwindow(dlgptr);
GetDItem(dlgptr, 4, >ype, &iphandle, &gbox);
sprintf(ipstr, "%d.%d.%d.%d", myipnum[0], myipnum[1],
myipnum[2], myipnum[3]);
c2pstr(ipstr);
SetIText(iphandle, ipstr);
/* ready to display the dialog */
ShowWindow(dlgptr);
arrowcursor();
/* frame the default selection */
framedflt(dlgptr);
/* show dialog */
filterProc = DlgFilter;
ModalDialog(filterProc, &itemHit);
DisposDialog(dlgptr);
}
void calcmask(long *mask) /* calculate mask from IP number */
{
if (!(myipnum[0] & 0x80))
(*mask) = 0xff000000; /* Class A */
else if ((myipnum[0] & 0xc0) == 0x80)
(*mask) = 0xffff0000; /* Class B */
else
(*mask) = 0xffffff00; /* Class C */
}
void tcpdflthost(unsigned char *s)
{
short rc;
rc = getstr(s, 256, 257);
if (rc != 0) strcpy(s, "?"); /* If "?", prompt will be issued */
}
long tcpgetrsrv(cnr *cp)
{
#ifdef TCPDRV
/* if (init) return(131072); */
if (cp->online) return(20480);
else return(40960);
#else
#pragma unused(cp)
/* if (init) return(135168); */
return(26624);
#endif
}
void tcplgin(cnr *cp)
{
/* initialize variables for new conn. */
login_init(cp);
/* attempt to get IP address for host */
cp->mp = Sgethost(cp->hostonly);
ShowAllErrors();
if (!(cp->mp)) { /* table lookup failed; try name server */
cp->myport = Sdomain(cp->hostonly);
sprintf(dbgmsg, "return code %d from Sdomain for %s",
cp->myport, cp->hostonly);
putln(dbgmsg);
if (cp->myport == -1) {
stoperr(domalrt, cp);
if (cp->apiopen) {
apiopenerr(openResFailed, cp);
}
removeconnection(cp);
}
else cp->connstate = 2;
}
else { /* open a connection from table lookup */
cp->myport = Snetopen(cp->mp, rdportnum(cp));
if (cp->myport < 0) {
stoperr(topnalrt, cp);
if (cp->apiopen) {
apiopenerr(openConnFailed, cp);
}
removeconnection(cp);
}
else cp->connstate = 3;
}
}
void tcplgout(char keep, cnr *cp)
{
if (cp->connstate > 0) netclose(cp->myport);
sessionlgout(keep, cp);
}
void tcp_end(void)
{
putln("tcp_end called");
if (kipreg) {
kpunregister(); /* un-register our address */
kipreg = 0;
}
if (tcpinitok) {
netshut(); /* undo Snetinit */
tcpinitok = 0;
}
NBuld(); /* unload NBP */
ATuld(); /* unload ATP */
if (rcvbuff != 0) {
DisposPtr(rcvbuff);
rcvbuff = 0;
}
#ifdef TCPDRV
if (needResClose) {
CloseResolver();
}
needResClose = 0;
#endif
}
/* tcpwrite - call netwrite to get all data written */
void tcpwrite(unsigned char *dptr, short dsize, cnr *cp)
{
short cnt;
static unsigned long * Ticks = (unsigned long *)0x16a;
unsigned long limit;
writeinfo *infoptr;
short infosize;
if (writedebug) {
infoptr = new_writeinfo(cp);
infoptr->start_ticks = *Ticks;
infoptr->length = dsize;
infosize = dsize;
if (infosize > INFODATASIZE) infosize = INFODATASIZE;
memcpy(infoptr->data, dptr, infosize);
}
if (dsize > 1) { /* skip for single characters */
cp->online = 0; /* for efficiency in line mode */
newstat(cp);
}
limit = (*Ticks) + 60 * cp->cs.timeout * cp->cs.retries;
while (dsize > 0) {
if (cp->cs.dblevel > 2) dbgdump("netwrite", dptr, dsize);
netpush(cp->myport);
cnt = netwrite(cp->myport, dptr, dsize);
if (writedebug) {
infoptr->calls++;
}
if (cp->cs.dblevel > 2) {
sprintf(dbgmsg, "netwrite wrote %d bytes", cnt);
putln(dbgmsg);
}
if (cnt > 0) {
dptr += cnt;
dsize -= cnt;
limit = (*Ticks) + 60 * cp->cs.timeout * cp->cs.retries;
}
myStask();
if ((*Ticks) > limit) {
if (writedebug) {
infoptr->end_ticks = *Ticks;
infoptr->result = 1;
}
cp->online = 0;
cp->kblcode = 3;
cp->ioerror = 4;
newstat(cp);
closeresponse(closeNetFail, cp);
tcplgout(1, cp);
stoperr(wrtalrt, cp);
return;
}
}
if (writedebug) {
infoptr->end_ticks = *Ticks;
infoptr->result = 0;
}
if (cp->online == 0) {
cp->online = 1;
newstat(cp);
}
}
void tcpin(unsigned char asc, unsigned char chr,
unsigned char shift, cnr *cp)
{
if (!(cp->logon)) { /* Return or CLEAR for new session, else beep */
if (cp->connstate == 0) kbnew(chr, cp);
else if ((cp->connstate == 4) && (!(cp->kblock)))
tcpkbin(asc, chr, shift, cp);
else beep(cp);
return;
}
if (chr == 196) { /* perform program reset immediately */
tcp_reset(cp);
xfrst(cp);
invldscr(cp);
return;
}
if (chr == 185) { /* perform keyboard immediately */
hndkbd(chr, shift, cp);
return;
}
if (chr == 197) { /* perform print screen immediately */
prscreen(cp);
return;
}
if ((cp->kbqsize == KBQMAX) || (cp->vmxbgn && (!(cp->vmxsub)))) {
beep(cp); /* error if xfer mode or queue full */
kerr(3, cp);
}
else { /* else add to keyboard queue */
(cp->kbqueue)[cp->kbqsize].code = chr;
(cp->kbqueue)[cp->kbqsize].shift = shift;
cp->kbqsize++;
}
}
void tcp_reset(cnr *cp)
{
if (cp->logon) {
cp->kblock = cp->kblcode = 0;
cp->online = 1;
}
cp->lastwcc = 0x02;
cp->kb_err = 0;
cp->kbqsize = 0;
cp->aplmode = cp->insmode = 0;
cp->fixbracket = cp->cs.std_brack && (!(cp->aplmode)) &&
(cp->stdfont != ALAFONT);
newstat(cp);
}
void ATuld(void) /* if necessary, unload .ATP driver */
{
CntrlParam cp;
if (sw_active() || (!unldATP)) return;
unldATP = 0;
cp.ioCRefNum = -11; /* .ATP reference number */
PBClose((ParmBlkPtr)&cp, 0);
}
OSErr NBld(void) /* load NBP */
{
CntrlParam cp;
OSErr rc;
if (unldNBP) return(0);
cp.ioCRefNum = -10; /* .MPP driver number */
cp.csCode = 249;
rc = PBControl((ParmBlkPtr)&cp, 0);
if (rc == 0) unldNBP = 1;
return(rc);
}
void NBuld(void) /* unload NBP */
{
CntrlParam cp;
if (!unldNBP) return;
cp.ioCRefNum = -10; /* .MPP driver number */
cp.csCode = 255;
PBControl((ParmBlkPtr)&cp, 0);
unldNBP = 0;
}
OSErr nblookup(unsigned char *object, unsigned char *type,
unsigned char *zone, NTElement *result, short *count)
{
MPPParamBlock Mpb;
OSErr rc;
unsigned char entity[99];
NBPSetEntity(entity, object, type, zone);
Mpb.NBPinterval = 3;
Mpb.NBPcount = 4;
Mpb.NBPentityPtr = entity;
Mpb.NBPretBuffPtr = (Ptr)result;
Mpb.NBPretBuffSize = sizeof(NTElement);
Mpb.NBPmaxToGet = 1;
Mpb.MPPioRefNum = -10; /* .MPP driver number */
Mpb.MPPcsCode = 251; /* lookup name */
rc = PBControl((ParmBlkPtr)&Mpb, 0);
(*count) = Mpb.NBPnumGotten;
return(rc);
}
OSErr atsend(AddrBlock *ablock, unsigned char *sendaddr,
short sendlen, BDSPtr retbds)
{
ATPParamBlock Apb;
OSErr rc;
Apb.ATPuserData = 0;
Apb.ATPcsCode = 255;
Apb.ATPioRefNum = -11;
Apb.ATPatpFlags = 0;
Apb.ATPaddrBlock = (*ablock);
Apb.ATPreqLength = sendlen;
Apb.ATPreqPointer = sendaddr;
Apb.ATPbdsPointer = (Ptr)retbds;
Apb.ATPnumOfBuffs = 1;
Apb.ATPtimeOutVal = 1; /* try every second */
Apb.ATPretryCount = 30; /* up to 30 times */
rc = PBControl((ParmBlkPtr)&Apb, 0);
return(rc);
}
OSErr kpdynamip(long *ipnum)
{
IPGP gateRec, gateSend;
BDSType retBDS;
OSErr rc;
putln("obtaining dynamic IP number");
retBDS[0].buffSize = sizeof(gateRec);
retBDS[0].buffPtr = (Ptr)&gateRec;
gateSend.opcode = 1;
rc = atsend((AddrBlock *)KIPserver, (unsigned char *)&gateSend,
sizeof(struct IPGP), (BDSPtr)retBDS);
if (rc != 0) return(rc);
(*ipnum) = gateRec.ipaddress;
return(0);
}
OSErr kpregister(unsigned char *ipnum)
{
MPPParamBlock Mpb;
OSErr rc;
unsigned char temps[20];
sprintf(temps, "%d.%d.%d.%d", ipnum[0], ipnum[1], ipnum[2], ipnum[3]);
sprintf(dbgmsg, "registering %s", temps);
putln(dbgmsg);
c2pstr(temps);
if (KIPnameptr) kpunregister();
KIPnameptr = (unsigned char *)&myreg;
memset(&myreg, 0, sizeof(NamesTableEntry));
NBPSetNTE((Ptr)&myreg, temps, "\pIPADDRESS", KIPzone, 72);
Mpb.MPPioRefNum = -10;
Mpb.MPPcsCode = 253;
Mpb.NBPinterval = 5;
Mpb.NBPcount = 5;
Mpb.NBPntQElPtr = (Ptr)&myreg;
Mpb.NBPverifyFlag = 1;
rc = PBControl((ParmBlkPtr)&Mpb, 0);
sprintf(dbgmsg, "rc = %d from NBPRegister", rc);
putln(dbgmsg);
return(rc);
}
void kpunregister(void)
{
MPPParamBlock Mpb;
OSErr rc;
Mpb.MPPioRefNum = -10;
Mpb.MPPcsCode = 252;
Mpb.NBPentityPtr = (Ptr)myreg.nt.entityData;
rc = PBControl((ParmBlkPtr)&Mpb, 0);
KIPnameptr = 0;
sprintf(dbgmsg, "rc = %d from NBPRemove", rc);
putln(dbgmsg);
}
OSErr openatdrv(void) /* open AppleTalk drivers */
{
static unsigned char *SPConfig = (unsigned char *)0x1fb;
static unsigned char *PortBUse = (unsigned char *)0x291;
IOParam openblk;
OSErr rc;
if ((*PortBUse & 0x80) == 0x80) { /* check if port B is in use */
/* port B not in use: */
if ((*SPConfig & 0x0f) > 1) { /* error unless unconfigured */
stoperr(portalrt, 0); /* or configured for AppleTalk */
return(-98);
}
else { /* else open MPP driver */
openblk.ioPermssn = 0;
openblk.ioNamePtr = (StringPtr)"\p.MPP";
rc = PBOpen((ParmBlkPtr)&openblk, 0);
if (rc != 0) {
stoperr(loadalrt, 0);
return(rc);
}
}
}
else { /* port B in use: */
if ((*PortBUse & 0x0f) != 1) { /* error if not in use by */
stoperr(portalrt, 0); /* AppleTalk */
return(-97);
}
}
/* load ATP if not already loaded */
if ((*PortBUse & 0x10) == 0) {
openblk.ioPermssn = 0;
openblk.ioNamePtr = (StringPtr)"\p.ATP";
rc = PBOpen((ParmBlkPtr)&openblk, 0);
if (rc != 0) {
stoperr(loadalrt, 0);
return(rc);
}
unldATP = 1; /* remember we loaded .ATP */
}
return(0);
}
int isHFS(void)
{
return(HFS);
}
cvtmask(long mask, unsigned char *s)
{
register short i, len;
sprintf(s, "%08lx", mask);
len = strlen(s);
for (i=0; i < len; i++)
s[i] = toupper(s[i]);
}
Boolean decodeIPnum(unsigned char *s, unsigned char *myipnum)
{
short i;
int node, hi, low;
unsigned char temp[50];
char addrflag;
for (i=0; i<4; i++) myipnum[i]=0;
i=0;
addrflag = 0;
while((*s) && (i<4) ) {
switch( *s) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
myipnum[i]= myipnum[i] *10 + (*s-'0');
break;
case '.':
i++;
break;
case 'H':
case 'h':
if (addrflag == 0) {
getATaddress( &hi, &low, &node);
addrflag = 1;
}
myipnum[i]=hi;
break;
case 'L':
case 'l':
if (addrflag == 0) {
getATaddress( &hi, &low, &node);
addrflag = 1;
}
myipnum[i]=low;
break;
case 'N':
case 'n':
if (addrflag == 0) {
getATaddress( &hi, &low, &node);
addrflag = 1;
}
myipnum[i]=node;
break;
default:
break;
}
s++;
}
sprintf( temp," IPNUM= %d.%d.%d.%d", (int) myipnum[0], (int) myipnum[1], (int) myipnum[2],
(int) myipnum[3]);
putln(temp);
if (i<3) return( 1);
else return( 0);
}
void ShowAllErrors(void)
{
int ev, what, dat;
ev = Sgetevent( ERRCLASS,&what,&dat);
while (ev) {
NetError(dat);
ev = Sgetevent( ERRCLASS,&what,&dat);
}
}
void NetError(int code)
{
unsigned char buffer1[100], buffer2[100];
int ev, what;
short class;
pascal Boolean (*filterProc) ();
static char nullstr[1] = {0};
buffer1[0]=0;
buffer2[0]=0;
if (code<0) {
strncpy( buffer2, neterrstring(code), 99);
ev = Sgetevent( ERRCLASS,&what,&code);
if (ev)
strncpy( buffer1, neterrstring(code), 99);
}
else
strncpy( buffer1, neterrstring(code), 99);
class = code/100;
if ((code == 402) || (code == 405)) class = 5;
if ((class==1 || class==5 || class==9) && (code!=503) ) {
/* Ok, I'll show the user these */
c2pstr(buffer1);
c2pstr(buffer2);
ParamText( buffer1, buffer2, nullstr, nullstr);
p2cstr(buffer1);
p2cstr(buffer2);
filterProc = DlgFilter;
arrowcursor();
if (class == 9) StopAlert(274, filterProc);
else if (class == 5) CautionAlert(275, filterProc);
else NoteAlert(276, filterProc);
ParamText(nullstr, nullstr, nullstr, nullstr);
}
if (buffer1[0])
putln(buffer1);
if (buffer2[0])
putln(buffer2);
}
void OtherError(unsigned char *mess1, unsigned char *mess2)
{
unsigned char buffer1[100], buffer2[100];
pascal Boolean (*filterProc) ();
static char nullstr[1] = {0};
buffer1[0]=0;
buffer2[0]=0;
strncpy(buffer1, mess1, 99);
strncpy(buffer2, mess2, 99);
c2pstr(buffer1);
c2pstr(buffer2);
ParamText( buffer1, buffer2, nullstr, nullstr);
filterProc = DlgFilter;
StopAlert(274, filterProc);
ParamText( nullstr, nullstr, nullstr, nullstr);
}
void tcpinfo(cnr *cp)
{
DialogPtr dlgptr;
DialogPeek dStorage;
WindowPtr behind;
short gtype, itemHit;
Rect gbox;
pascal Boolean (*filterProc) ();
Handle hosth, iph, stath;
unsigned char ipstr[20];
dStorage = 0;
behind = (WindowPtr)-1;
dlgptr = GetNewDialog(277, dStorage, behind);
ctrwindow(dlgptr);
/* get handles we will need */
GetDItem(dlgptr, 3, >ype, &hosth, &gbox);
GetDItem(dlgptr, 5, >ype, &iph, &gbox);
GetDItem(dlgptr, 7, >ype, &stath, &gbox);
/* set host name */
if (cp->connstate < 2) {
c2pstr(cp->hostonly);
SetIText(hosth, cp->hostonly);
p2cstr(cp->hostonly);
}
else if ((cp->mp)->hname == 0) {
if ((cp->mp)->sname == 0) SetIText(hosth, "\punknown");
else if (strcmp((cp->mp)->sname, "default") == 0)
SetIText(hosth, "\punknown");
else {
c2pstr((cp->mp)->sname);
SetIText(hosth, (cp->mp)->sname);
p2cstr((cp->mp)->sname);
}
}
else {
c2pstr((cp->mp)->hname);
SetIText(hosth, (cp->mp)->hname);
p2cstr((cp->mp)->hname);
}
/* set ip number */
if (cp->connstate < 3) SetIText(iph, "\punknown");
else {
sprintf(ipstr, "%d.%d.%d.%d", (cp->mp)->hostip[0],
(cp->mp)->hostip[1], (cp->mp)->hostip[2], (cp->mp)->hostip[3]);
c2pstr(ipstr);
SetIText(iph, ipstr);
}
/* set status */
switch (cp->connstate) {
case 0: /* waiting for name server */
SetIText(stath, "\pIdle - press Return to open a connection");
break;
case 2: /* waiting for name server */
SetIText(stath, "\pwaiting for response from name server");
break;
case 3: /* waiting for connection */
SetIText(stath, "\pwaiting for connection to complete");
break;
case 4: /* negotiating settings */
if (cp->hadascii) SetIText(stath, "\pconnected in line mode");
else SetIText(stath, "\pconnected: negotiating settings");
break;
case 5: /* if 0, must be logged on */
SetIText(stath, "\p3270 session established");
break;
default: /* shouldn't happen */
SetIText(stath, "\pI'm confused -- status unknown");
break;
}
/* ready to display the dialog */
ShowWindow(dlgptr);
arrowcursor();
/* frame the default selection */
framedflt(dlgptr);
/* display the dialog until OK selected */
filterProc = DlgFilter;
itemHit = 0;
while (itemHit != 1) ModalDialog(filterProc, &itemHit);
DisposDialog(dlgptr);
}
int tcp_session(cnr *cp) /* return TRUE if session active */
{
return(cp->logon || (cp->hadascii && (cp->connstate == 4)));
}
short rdportnum(cnr *cp)
/* return port number from connhostname, or default */
{
register short i, count, len, port;
register unsigned char *s;
len = strlen(cp->connhostname);
if (len < 3) return(HTELNET); /* need at least two colons and digit */
count = 0;
for (i=0; i < len; i++) {
if ((cp->connhostname)[i] == ':') count++;
if (count == 2) break;
}
if (count < 2) return(HTELNET);
s = cp->connhostname + i + 1; /* s = host number string */
if (s[0] == '\0') return(HTELNET);
if ((strcmp(s, "IRC") == 0) || (strcmp(s, "irc") == 0)) {
cp->serverconn = 1;
cp->servermode = 0;
cp->serverflags = 1;
port = 6667;
}
else if ((strcmp(s, "SMTP") == 0) || (strcmp(s, "smtp") == 0)) {
cp->serverconn = 1;
cp->servermode = 0;
cp->serverflags = 0;
port = 25;
}
else if ((strncmp(s, "SERVER=", 7) == 0) || (strncmp(s, "server=", 7) == 0)) {
cp->serverconn = 1;
cp->servermode = 0;
cp->serverflags = 0;
port = atoi(s+7);
}
else {
cp->serverconn = cp->servermode = cp->serverflags = 0;
port = atoi(s);
}
if (port == 0) {
sprintf(dbgmsg, "Port specification %s is invalid", s);
putln(dbgmsg);
stoperr(pnumalrt, cp);
port = HTELNET;
}
if (cp->serverconn) {
sprintf(dbgmsg, "Using non-Telnet connection mode");
putln(dbgmsg);
}
sprintf(dbgmsg, "port number = %d", port);
putln(dbgmsg);
return(port);
}
OSErr getstr(unsigned char *s, short lim, short num)
{
short rfile, rc;
Handle temph;
unsigned char * tempp;
sysvol(0);
rfile = OpenResFile(CFIGFILE);
if (rfile != -1) {
temph = GetResource('STR ', num);
if (temph != 0) if (HomeResFile(temph) == rfile) {
tempp = *temph;
if (tempp[0] > lim-1) rc = 12;
else {
memcpy(s, tempp, tempp[0]+1);
p2cstr(s);
sprintf(dbgmsg, "STR %d = \"%s\"", num, s);
putln(dbgmsg);
rc = 0;
}
}
else rc = 8;
CloseResFile(rfile);
}
else rc = 4;
sysvol(1);
sprintf(dbgmsg, "getstr rc = %d for STR %d", rc, num);
putln(dbgmsg);
return(rc);
}
void sysvol(short reset)
{
unsigned char strbuff[256];
static short dfltvol;
if (reset) SetVol(0L, dfltvol);
else {
GetVol(strbuff, &dfltvol);
SetVol(0L, systemvol);
}
}
void tcpquit(OSErr rc)
{
/* error "rc" from opening MacTCP */
sprintf(dbgmsg, "Unable to open MacTCP. Result code = %d.", rc);
stopterr(dbgmsg, 0);
quit();
}
void quit(void)
{
ioend();
macend();
ExitToShell();
}
void DisplayMacBinary(void)
{
}
void checkhostfile(void)
{
OSErr rc;
short fnum;
Point where;
ProcPtr fileFilter;
DlgHookProcPtr dlgHook;
short numTypes;
SFTypeList typeList;
SFReply reply;
unsigned char hostfile[12];
strcpy(hostfile, "config.tel");
rc = fsrdopen(hostfile, savedvol, &fnum);
if (rc == 0) {
FSClose(fnum);
return;
}
/* couldn't find the file on the default volume, so try the launch volume */
SetVol(0L, launchvol);
rc = fsrdopen(hostfile, launchvol, &fnum);
if (rc == 0) {
FSClose(fnum);
return;
}
/* now try the system volume */
SetVol(0L, systemvol);
rc = fsrdopen(hostfile, systemvol, &fnum);
if (rc == 0) {
FSClose(fnum);
return;
}
/* finally, allow the user to locate it */
SetVol(0L, savedvol);
note_err(hostfalrt, 0); /* tell users what to do with SFGetFile */
where = sfgpoint;
fileFilter = 0;
numTypes = 1;
typeList[0] = 'TEXT';
dlgHook = 0;
arrowcursor();
SFGetFile(where, "\pSelect the file \"config.tel\":",
(FileFilterProcPtr)fileFilter, numTypes, typeList, dlgHook, &reply);
if (reply.good == 0) return;
SetVol(0L, reply.vRefNum);
}
/* dummy routine to allow linking with NCSA/BYU code */
void userftpd(int code, int myport)
{
#pragma unused(code, myport)
}
/* routine use in NCSA to display FTP messages */
void ftpmess(unsigned char *s)
{
putln("FTP message:");
putln(s);
}